//
// Created by 29108 on 2025/7/5.
//

#ifndef THREAD_POOL_H
#define THREAD_POOL_H


#include <vector>
#include <queue>
#include <memory>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <future>
#include <functional>
#include <stdexcept>
#include <atomic>
#include <chrono>
#include "common/config/config_manager.h"

namespace common {
    namespace thread_pool {
        class ThreadPool {
        public:

            struct Config {
                // ==================== 线程池基础配置 ====================
                int core_pool_size = 4;
                int maximum_pool_size = 16;
                int keep_alive_time_ms = 60000;
                int queue_capacity = 1000;

                // ==================== 线程池高级配置 ====================
                bool allow_core_thread_timeout = false;
                std::string rejection_policy = "abort"; // abort/discard/caller_runs
                bool prestart_all_core_threads = false;
                int thread_priority = 0;
                std::string thread_name_prefix = "pool-";

                // ==================== 监控配置 ====================
                bool enable_monitoring = true;
                int monitoring_interval_ms = 5000;
                bool enable_thread_dump = false;

                /**
                 * @brief 从ConfigManager加载线程池配置
                 */
                static Config fromConfigManager() {
                    auto& config = common::config::ConfigManager::getInstance();
                    Config result;

                    // 基础配置
                    result.core_pool_size = config.get<int>("thread_pool.core_pool_size", 4);
                    result.maximum_pool_size = config.get<int>("thread_pool.maximum_pool_size", 16);
                    result.keep_alive_time_ms = config.get<int>("thread_pool.keep_alive_time_ms", 60000);
                    result.queue_capacity = config.get<int>("thread_pool.queue_capacity", 1000);

                    // 高级配置
                    result.allow_core_thread_timeout = config.get<bool>("thread_pool.allow_core_thread_timeout", false);
                    result.rejection_policy = config.get<std::string>("thread_pool.rejection_policy", "abort");
                    result.prestart_all_core_threads = config.get<bool>("thread_pool.prestart_all_core_threads", false);
                    result.thread_priority = config.get<int>("thread_pool.thread_priority", 0);
                    result.thread_name_prefix = config.get<std::string>("thread_pool.thread_name_prefix", "pool-");

                    // 监控配置
                    result.enable_monitoring = config.get<bool>("thread_pool.enable_monitoring", true);
                    result.monitoring_interval_ms = config.get<int>("thread_pool.monitoring_interval_ms", 5000);
                    result.enable_thread_dump = config.get<bool>("thread_pool.enable_thread_dump", false);

                    return result;
                }

                /**
                 * @brief 验证线程池配置
                 */
                void validate() const {
                    if (core_pool_size <= 0) {
                        throw std::runtime_error("ThreadPool core_pool_size must be > 0");
                    }
                    if (maximum_pool_size < core_pool_size) {
                        throw std::runtime_error("ThreadPool maximum_pool_size must be >= core_pool_size");
                    }
                    if (queue_capacity <= 0) {
                        throw std::runtime_error("ThreadPool queue_capacity must be > 0");
                    }
                    if (keep_alive_time_ms < 0) {
                        throw std::runtime_error("ThreadPool keep_alive_time_ms must be >= 0");
                    }
                    if (rejection_policy != "abort" && rejection_policy != "discard" && rejection_policy != "caller_runs") {
                        throw std::runtime_error("Invalid ThreadPool rejection_policy: " + rejection_policy);
                    }
                }
            };


            explicit ThreadPool();
            explicit ThreadPool(const Config& config);
            ~ThreadPool();

            // 提交任务并返回future
            template<class F, class... Args>
            auto submit(F&& f, Args&&... args)
                -> std::future<typename std::result_of<F(Args...)>::type>;

            // 获取统计信息
            size_t getQueueSize() const;
            size_t getActiveThreadCount() const;
            size_t getTotalThreadCount() const;

            // 优雅关闭
            void shutdown();
            void forceShutdown();  // 强制立即关闭
            bool isShutdown() const;

            /**
            * @brief 启用配置热更新监听
            */
            void enableConfigHotReload();

            /**
             * @brief 动态调整核心线程池大小
             * @param new_core_size 新的核心线程数
             * @details 实现线程池核心线程数的动态调整
             */
            void adjustCorePoolSize(int new_core_size);

            /**
             * @brief 动态调整最大线程池大小
             * @param new_max_size 新的最大线程数
             */
            void adjustMaximumPoolSize(int new_max_size);

            /**
             * @brief 停止监控功能
             */
            void stopMonitoring();

        private:
            Config config_;
            std::vector<std::thread> workers_;
            std::queue<std::function<void()>> tasks_;

            mutable std::mutex queue_mutex_;
            std::condition_variable condition_;
            std::atomic<bool> stop_;
            std::atomic<size_t> active_threads_;

            std::atomic<int> core_threads_to_reduce_{0};           ///< 需要减少的核心线程数
            std::atomic<int> threads_to_terminate_{0};             ///< 需要终止的线程数
            std::atomic<bool> monitoring_enabled_{false};          ///< 监控是否启用
            std::thread monitoring_thread_;                        ///< 监控线程

            /**
            * @brief 工作线程函数
            */
            void workerThread();

            /**
             * @brief 启动监控功能
             * @details 启动线程池监控线程，定期报告状态
             */
            void startMonitoring();

            /**
             * @brief 报告线程池状态
             */
            void reportPoolStatus();


        };

        template<class F, class ... Args>
        auto ThreadPool::submit(F &&f, Args &&...args) -> std::future<typename std::result_of<F(Args...)>::type> {

            using return_type = typename std::result_of<F(Args...)>::type;

            // 创建packaged_task来包装任务
            auto task = std::make_shared<std::packaged_task<return_type()>>(
                std::bind(std::forward<F>(f), std::forward<Args>(args)...)
            );

            std::future<return_type> res = task->get_future();

            {
                std::unique_lock<std::mutex> lock(queue_mutex_);

                // 如果线程池已经停止，不接受新任务
                if (stop_) {
                    throw std::runtime_error("submit on stopped ThreadPool");
                }
                // 将任务添加到队列
                tasks_.emplace([task](){ (*task)(); });
            }

            // 通知一个等待的线程
            condition_.notify_one();
            return res;
        }

    }
}



#endif //THREAD_POOL_H
